home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / games / nhak_src.zip / MKROOM.C < prev    next >
C/C++ Source or Header  |  1993-03-16  |  12KB  |  493 lines

  1. /*    SCCS Id: @(#)mkroom.c    3.0    88/11/24
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. /*
  6.  * Entry points:
  7.  *    mkroom() -- make and stock a room of a given type
  8.  *    nexttodoor() -- return TRUE if adjacent to a door
  9.  *    has_dnstairs() -- return TRUE if given room has a down staircase
  10.  *    has_upstairs() -- return TRUE if given room has an up staircase
  11.  *    dist2() -- Euclidean square-of-distance function
  12.  *    courtmon() -- generate a court monster
  13.  */
  14.  
  15. #define MONATTK_H    /* comment line for pre-compiled headers */
  16. /* block some unused #defines to avoid overloading some cpp's */
  17. #include "hack.h"
  18.  
  19. #ifdef OVLB
  20. static boolean FDECL(isbig, (struct mkroom *));
  21. static struct mkroom * FDECL(pick_room,(BOOLEAN_P));
  22. static void NDECL(mkshop), FDECL(mkzoo,(int)), NDECL(mkswamp);
  23. #ifdef ORACLE
  24. static void NDECL(mkdelphi);
  25. #endif
  26. #if defined(ALTARS) && defined(THEOLOGY)
  27. static void NDECL(mktemple);
  28. #endif
  29.  
  30. static struct permonst * NDECL(morguemon);
  31. #ifdef ARMY
  32. static struct permonst * NDECL(squadmon);
  33. #endif
  34. #endif /* OVLB */
  35.  
  36. #define sq(x) ((x)*(x))
  37.  
  38. #ifdef OVLB
  39.  
  40. static boolean
  41. isbig(sroom)
  42. register struct mkroom *sroom;
  43. {
  44.     register int area = (sroom->hx - sroom->lx) * (sroom->hy - sroom->ly);
  45.     return( area > 20 );
  46. }
  47.  
  48. void
  49. mkroom(roomtype)
  50. /* make and stock a room of a given type */
  51. int    roomtype;
  52. {
  53.  
  54.     if (roomtype >= SHOPBASE)
  55.     mkshop();    /* someday, we should be able to specify shop type */
  56.     else switch(roomtype) {
  57. #ifdef THRONES
  58.     case COURT:    mkzoo(COURT); break;
  59. #endif
  60.     case ZOO:    mkzoo(ZOO); break;
  61.     case BEEHIVE:    mkzoo(BEEHIVE); break;
  62.     case MORGUE:    mkzoo(MORGUE); break;
  63.     case BARRACKS:    mkzoo(BARRACKS); break;
  64.     case SWAMP:    mkswamp(); break;
  65. #ifdef ORACLE
  66.     case DELPHI:    mkdelphi(); break;
  67. #endif
  68. #if defined(ALTARS) && defined(THEOLOGY)
  69.     case TEMPLE:    mktemple(); break;
  70. #endif
  71.     default:    impossible("Tried to make a room of type %d.", roomtype);
  72.     }
  73. }
  74.  
  75. static void
  76. mkshop()
  77. {
  78.     register struct mkroom *sroom;
  79.     int i = -1;
  80. #ifdef WIZARD
  81. # ifdef __GNULINT__
  82.     register char *ep = (char *)0;
  83. # else
  84.     register char *ep;
  85. # endif
  86.  
  87.     /* first determine shoptype */
  88.     if(wizard){
  89.         ep = getenv("SHOPTYPE");
  90.         if(ep){
  91.             if(*ep == 'z' || *ep == 'Z'){
  92.                 mkzoo(ZOO);
  93.                 return;
  94.             }
  95.             if(*ep == 'm' || *ep == 'M'){
  96.                 mkzoo(MORGUE);
  97.                 return;
  98.             }
  99.             if(*ep == 'b' || *ep == 'B'){
  100.                 mkzoo(BEEHIVE);
  101.                 return;
  102.             }
  103. #ifdef THRONES
  104.             if(*ep == 't' || *ep == 'T' || *ep == '\\'){
  105.                 mkzoo(COURT);
  106.                 return;
  107.             }
  108. #endif
  109. #ifdef ARMY
  110.             if(*ep == 's' || *ep == 'S'){
  111.                 mkzoo(BARRACKS);
  112.                 return;
  113.             }
  114. #endif /* ARMY */
  115. #if defined(ALTARS) && defined(THEOLOGY)
  116.             if(*ep == '_'){
  117.                 mktemple();
  118.                 return;
  119.             }
  120. #endif
  121.             if(*ep == '}'){
  122.                 mkswamp();
  123.                 return;
  124.             }
  125.             for(i=0; shtypes[i].name; i++)
  126.                 if(*ep == shtypes[i].symb) goto gottype;
  127.             if(*ep == 'g' || *ep == 'G')
  128.                 i = 0;
  129.             else
  130.                 i = -1;
  131.         }
  132.     }
  133. gottype:
  134. #endif
  135.     for(sroom = &rooms[0]; ; sroom++){
  136.         if(sroom->hx < 0) return;
  137.         if(sroom - rooms >= nroom) {
  138.             pline("rooms not closed by -1?");
  139.             return;
  140.         }
  141.         if(sroom->rtype != OROOM) continue;
  142.         if(!sroom->rlit || has_dnstairs(sroom) || has_upstairs(sroom))
  143.             continue;
  144.         if(
  145. #ifdef WIZARD
  146.            (wizard && ep && sroom->doorct != 0) ||
  147. #endif
  148.             sroom->doorct == 1) break;
  149.     }
  150.  
  151.     if(i < 0) {            /* shoptype not yet determined */
  152.         register int j;
  153.  
  154.         /* pick a shop type at random */
  155.         for(j = rn2(100), i = 0; j -= shtypes[i].prob; i++)
  156.         if (j < 0)    break;
  157.  
  158.         /* big rooms cannot be wand or book shops,
  159.          * - so make them general stores
  160.          */
  161.         if(isbig(sroom) && (shtypes[i].symb == WAND_SYM
  162. #ifdef SPELLS
  163.                 || shtypes[i].symb == SPBOOK_SYM
  164. #endif
  165.                                 )) i = 0;
  166.     }
  167.     sroom->rtype = SHOPBASE + i;
  168.  
  169.     /* stock the room with a shopkeeper and artifacts */
  170.     stock_room(&(shtypes[i]), sroom);
  171. }
  172.  
  173. static struct mkroom *
  174. pick_room(strict)
  175. register boolean strict;
  176. /* pick an unused room, preferably with only one door */
  177. {
  178.     register struct mkroom *sroom;
  179.     register int i = nroom;
  180.  
  181.     for(sroom = &rooms[rn2(nroom)]; i--; sroom++) {
  182.         if(sroom == &rooms[nroom])
  183.             sroom = &rooms[0];
  184.         if(sroom->hx < 0)
  185.             return (struct mkroom *)0;
  186.         if(sroom->rtype != OROOM)    continue;
  187.         if(!strict) {
  188.             if(has_upstairs(sroom) || (has_dnstairs(sroom) && rn2(3)))
  189.             continue;
  190.         } else if(has_upstairs(sroom) || has_dnstairs(sroom))
  191.             continue;
  192.         if(sroom->doorct == 1 || !rn2(5))
  193.             return sroom;
  194.     }
  195.     return (struct mkroom *)0;
  196. }
  197.  
  198. static void
  199. mkzoo(type)
  200. int type;
  201. {
  202.     register struct mkroom *sroom;
  203.     struct monst *mon;
  204.     register int sx,sy,i;
  205.     int sh, tx, ty, goldlim = 500 * dlevel;
  206.  
  207.     if(!(sroom = pick_room(FALSE))) return;
  208.  
  209.     sroom->rtype = type;
  210.     sh = sroom->fdoor;
  211.     switch(type) {
  212. #ifdef __GNULINT__
  213.         default:
  214.         /* make sure tx and ty are initialized */
  215. #endif
  216.         case COURT:
  217.         tx = somex(sroom); ty = somey(sroom); break;
  218.         /* TODO: try to ensure the enthroned monster is an M2_PRINCE */
  219.         case BEEHIVE:
  220.         tx = sroom->lx + (sroom->hx - sroom->lx + 1)/2;
  221.         ty = sroom->ly + (sroom->hy - sroom->ly + 1)/2;
  222.         break;
  223.     }
  224.     for(sx = sroom->lx; sx <= sroom->hx; sx++)
  225.         for(sy = sroom->ly; sy <= sroom->hy; sy++){
  226.         if((sx == sroom->lx && doors[sh].x == sx-1) ||
  227.            (sx == sroom->hx && doors[sh].x == sx+1) ||
  228.            (sy == sroom->ly && doors[sh].y == sy-1) ||
  229.            (sy == sroom->hy && doors[sh].y == sy+1)) continue;
  230.         mon = makemon(
  231. #ifdef THRONES
  232.             (type == COURT) ? courtmon() :
  233. #endif
  234. #ifdef ARMY
  235.             (type == BARRACKS) ? squadmon() :
  236. #endif
  237.             (type == MORGUE) ? morguemon() :
  238.             (type == BEEHIVE) ?
  239.             (sx == tx && sy == ty ? &mons[PM_QUEEN_BEE] : 
  240.              &mons[PM_KILLER_BEE]) :
  241.             (struct permonst *) 0,
  242.            sx, sy);
  243.         if(mon) {
  244.             mon->msleep = 1;
  245. #ifdef THRONES
  246.             if (type==COURT && mon->mpeaceful) {
  247.                 mon->mpeaceful = 0;
  248.                 mon->malign = max(3,abs(mon->data->maligntyp));
  249.             }
  250. #endif
  251.         }
  252.         switch(type) {
  253.             case ZOO:
  254.             i = sq(dist2(sx,sy,doors[sh].x,doors[sh].y));
  255.             if(i >= goldlim) i = 5*dlevel;
  256.             goldlim -= i;
  257.             mkgold((long)(10 + rn2(i)), sx, sy);
  258.             break;
  259.             case MORGUE:
  260.             if(!rn2(5))
  261.                 (void) mk_tt_object(CORPSE, sx, sy);
  262.             if(!rn2(10))    /* lots of treasure buried with dead */
  263.                 (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, sx, sy);
  264.             break;
  265.             case BEEHIVE:
  266.             if(!rn2(3))
  267.                 (void) mksobj_at(LUMP_OF_ROYAL_JELLY, sx, sy);
  268.             break;
  269.             case BARRACKS:
  270.             if(!rn2(20))    /* the payroll and some loot */
  271.                 (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, sx, sy);
  272.             break;
  273.         }
  274.     }
  275. #ifdef THRONES
  276.     if(type == COURT)  {
  277.         levl[tx][ty].typ = THRONE;
  278.         levl[tx][ty].scrsym = THRONE_SYM;
  279.  
  280.         sx = somex(sroom);
  281.         sy = somey(sroom);
  282.         mkgold((long) rn1(50 * dlevel,10), sx, sy);
  283.         (void) mksobj_at(CHEST, sx, sy);    /* the royal coffers */
  284.     }
  285. #endif
  286.  
  287. }
  288.  
  289. static struct permonst *
  290. morguemon()
  291. {
  292.     register int i = rn2(100), hd = rn2(dlevel);
  293.  
  294.     if(hd > 10 && i < 10)
  295.         return((Inhell) ? mkclass(S_DEMON) : &mons[ndemon()]);
  296.     if(hd > 8 && i > 85)
  297.         return(mkclass(S_VAMPIRE));
  298.  
  299.     return((i < 20) ? &mons[PM_GHOST]
  300.             : (i < 40) ? &mons[PM_WRAITH] : mkclass(S_ZOMBIE));
  301. }
  302.  
  303. static void
  304. mkswamp()    /* Michiel Huisjes & Fred de Wilde */
  305. {
  306.     register struct mkroom *sroom;
  307.     register int sx,sy,i,eelct = 0;
  308.  
  309.     for(i=0; i<5; i++) {        /* 5 tries */
  310.         sroom = &rooms[rn2(nroom)];
  311.         if(sroom->hx < 0 || sroom->rtype != OROOM ||
  312.            has_upstairs(sroom) || has_dnstairs(sroom))
  313.             continue;
  314.  
  315.         /* satisfied; make a swamp */
  316.         sroom->rtype = SWAMP;
  317.         for(sx = sroom->lx; sx <= sroom->hx; sx++)
  318.         for(sy = sroom->ly; sy <= sroom->hy; sy++)
  319.         if(!OBJ_AT(sx, sy) && levl[sx][sy].gmask == 0 &&
  320.            !MON_AT(sx, sy) && !t_at(sx,sy) && !nexttodoor(sx,sy)) {
  321.             if((sx+sy)%2) {
  322.             levl[sx][sy].typ = POOL;
  323.             levl[sx][sy].scrsym = POOL_SYM;
  324.             if(!eelct || !rn2(4)) {
  325.                 (void) makemon(mkclass(S_EEL), sx, sy);
  326.                 eelct++;
  327.             }
  328.             } else if(!rn2(4))    /* swamps tend to be moldy */
  329.             (void) makemon(mkclass(S_FUNGUS), sx, sy);
  330.         }
  331.     }
  332. }
  333.  
  334. #ifdef ORACLE
  335. static void
  336. mkdelphi()
  337. {
  338.     register struct mkroom *sroom;
  339.     register struct monst *oracl;
  340.     int dy,xx,yy;
  341.  
  342.     if(doorindex >= DOORMAX) return;
  343.     if(!(sroom = pick_room(FALSE))) return;
  344.  
  345.     if(!place_oracle(sroom,&dy,&xx,&yy)) return;
  346.  
  347.     if(MON_AT(xx, yy))
  348.         rloc(m_at(xx, yy)); /* insurance */
  349.  
  350.     /* set up Oracle and environment */
  351.     if(!(oracl = makemon(&mons[PM_ORACLE],xx,yy))) return;
  352.     sroom->rtype = DELPHI;
  353.     oracl->mpeaceful = 1;
  354.  
  355.     yy -= dy;
  356.     if(accessible(xx-1, yy))
  357.         (void) mkcorpstat(STATUE, &mons[PM_FOREST_CENTAUR], xx-1, yy);
  358.     if(accessible(xx, yy))
  359.         (void) mkcorpstat(STATUE, &mons[PM_MOUNTAIN_CENTAUR], xx, yy);
  360.     if(accessible(xx+1,yy))
  361.         (void) mkcorpstat(STATUE, &mons[PM_PLAINS_CENTAUR], xx+1, yy);
  362. # ifdef FOUNTAINS
  363.     mkfount(0,sroom);
  364. # endif
  365. }
  366. #endif
  367.  
  368. #if defined(ALTARS) && defined(THEOLOGY)
  369. void
  370. shrine_pos(sx,sy,troom)
  371. int *sx,*sy;
  372. struct mkroom *troom;
  373. {
  374.     *sx = troom->lx + ((troom->hx - troom->lx) / 2);
  375.     *sy = troom->ly + ((troom->hy - troom->ly) / 2);
  376. }
  377.  
  378. static void
  379. mktemple()
  380. {
  381.     register struct mkroom *sroom;
  382.     int sx,sy;
  383.  
  384.     if(!(sroom = pick_room(TRUE))) return;
  385.  
  386.     /* set up Priest and shrine */
  387.     sroom->rtype = TEMPLE;
  388.     shrine_pos(&sx,&sy,sroom);
  389.     /*
  390.      * In temples, shrines are blessed altars
  391.      * located in the center of the room
  392.      */
  393.     levl[sx][sy].typ = ALTAR;
  394.     levl[sx][sy].scrsym = ALTAR_SYM;
  395.     levl[sx][sy].altarmask = rn2((int)A_LAW+1);
  396.     priestini(dlevel, sx, sy, (int) levl[sx][sy].altarmask);
  397.      levl[sx][sy].altarmask |= A_SHRINE;
  398. }
  399. #endif
  400.  
  401. boolean
  402. nexttodoor(sx,sy)
  403. register int sx, sy;
  404. {
  405.     register int dx, dy;
  406.     register struct rm *lev;
  407.     for(dx = -1; dx <= 1; dx++) for(dy = -1; dy <= 1; dy++) {
  408.         if(!isok(sx+dx, sy+dy)) continue;
  409.         if(IS_DOOR((lev = &levl[sx+dx][sy+dy])->typ) ||
  410.             lev->typ == SDOOR)
  411.             return(TRUE);
  412.     }
  413.     return(FALSE);
  414. }
  415.  
  416. boolean
  417. has_dnstairs(sroom)
  418. register struct mkroom *sroom;
  419. {
  420.     return(sroom->lx <= xdnstair && xdnstair <= sroom->hx &&
  421.            sroom->ly <= ydnstair && ydnstair <= sroom->hy);
  422. }
  423.  
  424. boolean
  425. has_upstairs(sroom)
  426. register struct mkroom *sroom;
  427. {
  428.     return(sroom->lx <= xupstair && xupstair <= sroom->hx &&
  429.            sroom->ly <= yupstair && yupstair <= sroom->hy);
  430. }
  431.  
  432. #endif /* OVLB */
  433. #ifdef OVL0
  434.  
  435. int
  436. dist2(x0,y0,x1,y1)
  437. int x0, y0, x1, y1;
  438. {
  439.     register int dx = x0 - x1, dy = y0 - y1;
  440.     return sq(dx) + sq(dy);
  441. }
  442.  
  443. #endif /* OVL0 */
  444. #ifdef OVLB
  445.  
  446. #ifdef THRONES
  447. struct permonst *
  448. courtmon()
  449. {
  450.     int     i = rn2(60) + rn2(3*dlevel);
  451.     if (i > 100)        return(mkclass(S_DRAGON));
  452.     else if (i > 95)    return(mkclass(S_GIANT));
  453.     else if (i > 85)    return(mkclass(S_TROLL));
  454.     else if (i > 75)    return(mkclass(S_CENTAUR));
  455.     else if (i > 60)    return(mkclass(S_ORC));
  456.     else if (i > 45)    return(&mons[PM_BUGBEAR]);
  457.     else if (i > 30)    return(&mons[PM_HOBGOBLIN]);
  458.     else if (i > 15)    return(mkclass(S_GNOME));
  459.     else            return(mkclass(S_KOBOLD));
  460. }
  461. #endif /* THRONES /**/
  462.  
  463. #ifdef ARMY
  464. #define        NSTYPES    (PM_CAPTAIN-PM_SOLDIER+1)
  465.  
  466. struct {
  467.     unsigned    pm;
  468.     unsigned    prob;
  469. }   squadprob[NSTYPES] = {
  470.     PM_SOLDIER, 80, PM_SERGEANT, 15, PM_LIEUTENANT, 4, PM_CAPTAIN, 1
  471. };
  472.  
  473. static struct permonst *
  474. squadmon() {        /* return soldier types. */
  475.  
  476.     register struct permonst *ptr;
  477.     register int    i, cpro, sel_prob = rnd(80+dlevel);
  478.  
  479.     for(cpro = i = 0; i < NSTYPES; i++)
  480.         if((cpro += squadprob[i].prob) > sel_prob) {
  481.  
  482.         ptr = &mons[squadprob[i].pm];
  483.         goto gotone;
  484.         }
  485.     ptr = &mons[squadprob[rn2(NSTYPES)].pm];
  486. gotone:
  487.     if(!(ptr->geno & G_GENOD))  return(ptr);
  488.     else                return((struct permonst *) 0);
  489. }
  490. #endif /* ARMY /* */
  491.  
  492. #endif /* OVLB */
  493.